package john.wenzi.filesclient.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import john.wenzi.filesclient.entity.FileUploadEntity;
import john.wenzi.filesclient.utils.AESUtil;
import john.wenzi.filesclient.utils.FinalBean;
import john.wenzi.filesclient.utils.RSAUtil;

@Controller
@RequestMapping("/file")
public class FileController {

	@Autowired
	private RestTemplate restTemplate;
	
	public static Logger logger = LoggerFactory.getLogger(FileController.class);
	
	@RequestMapping("/index")
	public String hello() {
		return "index";
	}
	@RequestMapping("/records")
	public String records() {
		return "records";
	}
	/**
	 * 上传文件
	 */
	@PostMapping("/upload")
	@ResponseBody
	public String fileUpload(@RequestParam("file")MultipartFile file) {
		logger.info("上传文件开始");
		try {
			//随机获取字符串
			String sid = RSAUtil.getRandomString(10);
			//获取签名
			String signature = RSAUtil.getSignature(sid);
			logger.info("签名："+signature);
			//设置请求头
	        HttpHeaders headers = new HttpHeaders();
	        MediaType type = MediaType.parseMediaType("multipart/form-data");
	        headers.setContentType(type);
	        headers.add("X-SID", sid);
	        headers.add("X-Signature", signature);
	        //生成临时文件
	        String tempFilePath = System.getProperty("java.io.tmpdir") + file.getOriginalFilename();
	        File tempFile = new File(tempFilePath);
	        file.transferTo(tempFile);
	        
	        //设置请求体
	        FileSystemResource fileSystemResource = new FileSystemResource(tempFile);
	        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
	        form.add("file", fileSystemResource);
	        form.add("filename",file.getName());
	        
	        //用HttpEntity封装整个请求报文
	        HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, headers);
	        //发送请求
	        String message = restTemplate.postForObject(FinalBean.UPLOAD_URL, files, String.class);
	        //删除临时文件文件
	        tempFile.delete();
	        logger.info("上传文件结束，UUID:"+message);
	        return message;
		}catch (Exception e) {
			logger.info("上传文件出现异常:"+e.getMessage());
			return "上传出现异常";
		}
    }
	/**
	 * 下载文件
	 * @param uuidName
	 */
	@RequestMapping("/download")
	@ResponseBody
	public String fileDownload(@RequestParam("uuidName")String uuidName, HttpServletResponse response) {
		logger.info("下载文件开始，参数uuidName："+uuidName);
		try {
			//随机获取字符串
			String sid = RSAUtil.getRandomString(10);
			//获取签名
			String signature = RSAUtil.getSignature(sid);
			//设置请求头
			HttpHeaders headers = new HttpHeaders();
			headers.add("fileName", uuidName);
			headers.add("X-SID", sid);
	        headers.add("X-Signature", signature);
	        //向服务端发送请求
			ResponseEntity<byte[]> entity = restTemplate.exchange(FinalBean.DOWNLOAD_URL, HttpMethod.GET,new HttpEntity<>(headers), byte[].class);
			//得到响应的字节数组
			byte[] body = entity.getBody();
			if(entity.getStatusCodeValue() == 410) {
				logger.info("下载文件出现异常。uuidName："+uuidName);
				return "下载文件出现异常！";
			}
			//获取数字信封
			List<String> list = entity.getHeaders().get("entryptDigitalEnvelope");
			String entryptKey = "";
			if(list != null && list.size() > 0) {
				entryptKey = list.get(0);
			}
			//获取私钥
			String privateKey =RSAUtil.getPrivateKey();
			//解密数字信封
			String key = RSAUtil.decrypt(entryptKey, privateKey);
			//得到解密结果
			byte[] b = AESUtil.decryptFile(body, key);
			//设置响应头
			response.setHeader("Content-Disposition", "attachment;filename=" + uuidName);
            response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.addHeader("Pragma", "no-cache");
            //文件下载类型--二进制文件
            response.setContentType("application/octet-stream");
            response.setHeader("Set-Cookie", "fileDownload=true; path=/");
            OutputStream out = response.getOutputStream();
            out.write(b);
            out.flush();
            out.close();
            logger.info("下载文件成功");
            return "下载文件成功";
		} catch (Exception e) {
			logger.info("下载文件出现异常:"+e.getMessage());
			return "下载文件出现异常！";
		}
	}
	/**
	 * 查询上传文件信息
	 */
	@RequestMapping("/find")
	@ResponseBody
	public FileUploadEntity findFileInfo(@RequestParam("uuidName")String uuidName) {
		logger.info("查询文件信息开始，参数uuidName："+uuidName);
		try {
			//随机获取字符串
			String sid = RSAUtil.getRandomString(10);
			//获取签名
			String signature = RSAUtil.getSignature(sid);
			
			//设置请求头
			HttpHeaders headers = new HttpHeaders();
			headers.add("fileName", uuidName);
			headers.add("X-SID", sid);
	        headers.add("X-Signature", signature);
	        //向服务端发送请求
	        ResponseEntity<String> entity = restTemplate.exchange(FinalBean.FIND_URL, HttpMethod.GET,new HttpEntity<>(headers), String.class);
	        //得到请求结果
	        String json = entity.getBody();
			json=new String(json.getBytes("iso-8859-1"),"utf-8");
			
	        FileUploadEntity fileUploadEntity = JSON.parseObject(json, FileUploadEntity.class);
	        logger.info("文件信息："+fileUploadEntity.toString());
	        return fileUploadEntity;
		}catch (Exception e) {
			logger.info("查询文件信息出现异常："+e.getMessage());
			return null;
		}
	}
	/**
	 * 查询历史上传文件信息
	 */
	@RequestMapping("/findall")
	@ResponseBody
	public List<FileUploadEntity> findAllFileInfo() {
		logger.info("查询历史上传文件信息开始");
		try {
			//随机获取字符串
			String sid = RSAUtil.getRandomString(10);
			//获取签名
			String signature = RSAUtil.getSignature(sid);
			//设置请求头
			HttpHeaders headers = new HttpHeaders();
			headers.add("X-SID", sid);
	        headers.add("X-Signature", signature);
	        //向客户端发送请求
	        ResponseEntity<String> entity = restTemplate.exchange(FinalBean.FIND_ALL_URL, HttpMethod.GET,new HttpEntity<>(headers), String.class);
	        //得到相应结果
	        String json = entity.getBody();
	        logger.info("服务端相应结果："+json);
			json=new String(json.getBytes("iso-8859-1"),"utf-8");
	        List<FileUploadEntity> list = JSONObject.parseArray(json, FileUploadEntity.class); 
	        logger.info("历史上传文件信息："+list.toString());
	        return list;
		}catch (Exception e) {
			logger.info("查询历史上传文件信息出现异常："+e.getMessage());
			return null;
		}
	}
	
}
